#include <iostream>
#include <memory>
/*场景：构建复杂对象*/

/*抽象电脑类*/
class Computer {
public:
    void set_board(const std::string &board) { board_ = board; }
    void set_display(const std::string &display) { display_ = display; }
    virtual void set_os() = 0;
    std::string show_paramaters() {
        std::string param = "The Computer Paramaters:\n";
        param += "\tboard: " + board_ + '\n';
        param += "\tdisplay: " + display_ + '\n';
        param += "\tos: " + os_ + '\n';
        return param;
    }
protected:
    std::string board_;
    std::string display_;
    std::string os_;
};
/*具体电脑类*/
class MacBook : public Computer {
public:
    //using ptr = std::shared_ptr<MacBook>;
    virtual void set_os() override { os_ = "Mac OS X12 Pro"; }
};

/*抽象builder类*/
/*抽象建造者类：包含创建⼀个产品对象的各个部件的抽象接⼝*/
class Builder {
public:
    virtual void build_board(const std::string &board) = 0;
    virtual void build_display(const std::string &display) = 0;
    virtual void build_os() = 0;
    virtual std::shared_ptr<Computer> build() = 0;
};
/*具体产品的builder类*/
/*具体产品的具体建造者类：实现抽象接⼝，构建和组装各个部件*/
class MackBookBuilder : public Builder{
public:
    MackBookBuilder() : computer_(new MacBook) {}
    virtual void build_board(const std::string &board) override {
        computer_->set_board(board);
    }
    virtual void build_display(const std::string &display) override {
        computer_->set_display(display);
    }
    virtual void build_os() override {
        computer_->set_os();
    }
    virtual std::shared_ptr<Computer> build() override {
        return computer_;
    }
    
private:
    std::shared_ptr<Computer> computer_;
};
/*指挥者Director类*/
/*指挥者类，提供给调⽤者使⽤，通过指挥者来构造复杂产品*/
class Director {
public:
    Director(Builder *builder) : builder_(builder) {}
    void construct(const std::string &board, const std::string &display) {
        builder_->build_board(board);
        builder_->build_display(display);
        builder_->build_os();
    }
private:
    std::shared_ptr<Builder> builder_;
};

int main() {
    Builder *builder = new MackBookBuilder;
    std::unique_ptr<Director> director(new Director(builder));
    director->construct("华硕主板", "ROG 显示器");
    std::shared_ptr<Computer> computer = builder->build();
    std::cout << computer->show_paramaters();
    return 0;
}
